#ifndef DYNAMICARRAY2_H
#define DYNAMICARRAY2_H

template <typename T>
class DynamicArray
{
public:
    DynamicArray(int size)
    {
        init(new T[size], size);
//        m_array = new T[size];
//        m_length = size;
    }

    DynamicArray(const DynamicArray<T> &da)
    {
        init(copy(da.m_array, da.m_length, da.m_length), da.m_length);
//        m_array = new T[da.m_length];
//        m_length = da.m_length;
//        for (int i = 0; i < m_length; i++)
//        {
//            m_array[i] = da.m_array[i];
//        }
    }

    DynamicArray& operator=(const DynamicArray<T> &da)
    {
        if (this != da)
        {
            update(copy(da.m_array, da.m_length, da.m_length), da.m_length);
//            T* array = new T[da.m_length];
//            for (int i = 0; i < da.m_length; i++)
//            {
//                array[i] = da.m_array[i];
//            }
//            T* temp = m_array;
//            m_array = array;
//            m_length = da.m_length;
//            delete[] temp;
        }
        return *this;
    }

    void resize(int newLength)
    {
        if (m_length == newLength)
            return;
        update(copy(m_array, m_length, newLength), newLength);
//        T *array = new T[newLength];
//        int size = (m_length > newLength ? newLength : m_length);
//        for (int i = 0; i < size; i++)
//        {
//            array[i] = m_array[i];
//        }
//        T* temp = m_array;
//        m_array = array;
//        m_length = newLength;
//        delete[] temp;
    }

    ~DynamicArray()
    {
        delete m_array;
    }

    int length()
    {
        return m_length;
    }

    T get(int i)
    {
        return operator[](i);
    }
    void set(int i, T value)
    {
        if (0 <= i && i < m_length)
        {
            m_array[i] = value;
        }
        else
        {
            throw "out of range";
        }
    }
    T& operator[](int i)
    {
        if (0 <= i && i < m_length)
        {
            return m_array[i];
        }
        else
        {
            throw "out of range";
        }
    }
    T operator[](int i) const
    {
        if (0 <= i && i < m_length)
        {
            return m_array[i];
        }
        else
        {
            throw "out of range";
        }
    }

protected:
    int m_length;
    T *m_array;
    void init(T *array, int length)
    {
        if (array != nullptr)
        {
            m_array = array;
            m_length = length;
        }
        else
        {
            throw "cannot init";
        }
    }
    T* copy(T *array, int length, int newLength)
    {
        T *ret = new T[newLength];
        if (ret != nullptr)
        {
            int size = (length > newLength ? newLength : length);
            for (int i = 0; i < size; i++)
            {
                ret[i] = array[i];
            }
        }
        else
        {
            throw "cannot init";
        }
        return ret;
    }
    void update(T *array, int length)
    {
        if (array != nullptr)
        {
            T* temp = m_array;
            m_array = array;
            m_length = length;
            delete[] temp;
        }
        else
        {
            throw "cannot init";
        }
    }

};


#endif // DYNAMICARRAY2_H
